package com.lancoo.ccas53.arrangecourse.AlgDataSource.dataprocess.Impl;

import com.lancoo.ccas53.arrangecourse.AlgDataSource.common.Constants;
import com.lancoo.ccas53.arrangecourse.AlgDataSource.dataprocess.TimeslotRoomDataService;
import com.lancoo.ccas53.pojo.dto.ArrangePeriod;
import com.lancoo.ccas53.pojo.dto.ArrangeRoomDto;
import com.lancoo.ccas53.pojo.dto.ArrangeRoomRuleDto;
import com.lancoo.ccas53.pojo.vo.Campus;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @Description 课时数据处理
 * @Author Fortysun
 * @Date 2023/4/13 14:42
 **/
public class TimeslotRoomDataServiceImpl extends PublicDataService implements TimeslotRoomDataService {
    private List<Campus> campusList;
    private HashMap<String, List<ArrangeRoomDto>> roomMap;
    private List<ArrangePeriod> timeslotList;

    public TimeslotRoomDataServiceImpl(List<Campus> campusList) {
        this.campusList = campusList;
        roomMap = new HashMap<>();
        timeslotList = new ArrayList<>();

        initRoomMap();
        initTimeslotList();
    }

    /**
     * 获取每个校区的教室禁排信息列表
     * @return
     */
    @Override
    public HashMap<String, List<ArrangeRoomRuleDto>> getRoomRuleMap() {
        //定义存储数据的map
        HashMap<String, List<ArrangeRoomRuleDto>> roomRuleMap = new HashMap<>();

        //统计每个校区30个教室
        int count = 0;
        for (Campus campus: campusList) {
            //定义存储每个校区的教室禁排信息列表
            List<ArrangeRoomRuleDto> roomRuleList = new ArrayList<>();
            List<ArrangeRoomDto> roomList = roomMap.get(campus.getCampusId());
            for (int i = 0; i < roomList.size(); i++) {
                if (count >= Constants.CAMPUS_ROOM_RULE_NUM) {
                    count = 0;
                    break;
                }

                roomRuleList.add(new ArrangeRoomRuleDto(
                        roomList.get(i).getRoomId(),
                        timeslotList.get(i%timeslotList.size()).getTimeCode()
                ));

                count++;

            }
            roomRuleMap.put(campus.getCampusId(), roomRuleList);
        }

        return roomRuleMap;
    }

    /**
     * 获取教室信息列表
     * @return
     */
    @Override
    public HashMap<String, List<ArrangeRoomDto>> getRoomMap() {
        return this.roomMap;
    }

    /**
     * 获取教师信息列表
     * @return
     */
    private void initRoomMap() {

        for (int i = 0; i < campusList.size(); i++) {
            //初始化每个校区的教室分配的比例
            List<Integer> hourTypeList = initHourType(Constants.CAMPUS_ROOM_NUM);
            //定义存储每个校区的教室信息；
            List<ArrangeRoomDto> roomList = new ArrayList<>();
            for (int j = 0; j < Constants.CAMPUS_ROOM_NUM; j++) {
                int index = i*Constants.CAMPUS_ROOM_NUM + j;
                //前一半的类型为讲授，后面的随机分配，1：讲授、2：实验、3：上机、4、其他
                int hourType = hourTypeList.get(j);
                Campus campus = campusList.get(i);
                roomList.add(new ArrangeRoomDto(
                        (long)(index+1),
                        getRoomNamePrefix(hourType) + (index+1),
                        1,
                        "惟义楼",
                        (Constants.CLASS_STUDENT_NUM+j),
                        getRoomType(hourType),
                        String.valueOf(hourType),
                        campus.getCampusId(),
                        campus.getCampusName(),
                        1
                ));
            }
            //将初始化好的，各个校区的教室数据，存入map
            roomMap.put(campusList.get(i).getCampusId(), roomList);
        }
    }

    /**
     * 根据不同的授课类型，指定不同类型的教室类型
     * @param hourType 授课类型 1：讲授，：实验、3：上机、4：其他
     * @return
     */
    private String getRoomNamePrefix(int hourType) {
        String roomNamePrefix = "";
        switch (hourType) {
            case 1:
                roomNamePrefix = "教室";//AI智慧教室
                break;
            case 2:
                roomNamePrefix="实验室";//实验室
                break;
            case 3:
                roomNamePrefix="机房";//普通电脑室，机房；
                break;
            case 4:
                roomNamePrefix ="操场";//操场；
                break;
            default:
                System.out.println("TimeslotRoomDataProcess--getRoomNamePrefix: hourType is not suitable, hourType=" + hourType);
                break;
        }
        return roomNamePrefix;
    }

    /**
     * 获取课时信息列表
     * @return
     */
    @Override
    public List<ArrangePeriod> getTimeslotList() {
        return this.timeslotList;
    }
    /**
     * 获取课时信息列表
     * @return
     */
    public List<ArrangePeriod> initTimeslotList() {

        for (int i = 0; i < Constants.ARRANGE_DAY_NUM; i++) {
            for (int j = 0; j < Constants.DAY_TIMESLOT_NUM; j++) {
                timeslotList.add(new ArrangePeriod(
                        "0"+(i+1)+ addZero(j+1),
                        covertToWeekName(i+1) + "第" + (j+1) + "节",
                        (j/4+1),
                        (j+1),0
                ));
            }
        }

        return timeslotList;
    }

    /**
     * 将每天的编号，转换成周一、周二、周三这种
     * @param index 每天的编号，1代表周一，2代表周二
     * @return
     */
    private String covertToWeekName(int index) {
        String weekName = "";
        switch (index) {
            case 1:
                weekName = "周一";
                break;
            case 2:
                weekName = "周二";
                break;
            case 3:
                weekName = "周三";
                break;
            case 4:
                weekName = "周四";
                break;
            case 5:
                weekName = "周五";
                break;
            default:
                System.out.println("TimeslotRoomDataServiceImpl--covertToWeekName: index is not suitable, index=" + index);
                break;
        }
        return weekName;
    }

    /**
     * timeCode的显示形式是0102这种，如果每天的课时编号小于0，需要补0
     * @param index 每天的课时编号
     * @return
     */
    private String addZero(int index) {
        String retStr = "";
        if (index < 10) {
            retStr = "0" + index;
        } else {
            retStr += index;
        }
        return retStr;
    }
}
